﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

public class UAVFunction:FlyItem
{
    public enum State
    {
        STATE_FIGHT,
        STATE_PROTECTED,
        STATE_BACK,
    }
    public WeaponSlot m_SlotOfUVA;
    public GameObject Target { 
        get { return m_Target; } 
        set { 
            m_Target = value;
            if (m_SlotOfUVA) 
                m_SlotOfUVA.Target = value;
            m_State = State.STATE_FIGHT;
        } 
    }
    public GameObject m_Target;
    public float m_HP;
    public float KeepDistanceWithMother = 10;
    public State m_State = State.STATE_FIGHT;
    public int m_AmmoCapacity = 1;
    public bool RotaDir = false;
    public bool SelfDestruct = false;

    public override void Awake()
    {
        m_SlotOfUVA.OnFireCallback = OnFireCallback;
        m_SlotOfUVA.hasFixedWeapon();
    }
    private void OnEnable()
    {
    }
    override public void Start()
    {
        m_HP = 111;
        base.Start();
    }
    public override void Update()
    {
        base.Update();
        if (UtilsGame.IsOnline() && !UtilsGame.IsServer(gameObject))
        {
            return;
        }

        if (Death)
            return;
        if (m_Ship == null)
        {
            OnBoom();
            return;
        }


        if (m_AmmoCapacity <= 0 || Life < 25)
            m_State = State.STATE_BACK;

        GameObject target = Target;
        CurFlyVelocity = FlyVelocity;
        switch(m_State)
        {
            case State.STATE_FIGHT:
                break;
            case State.STATE_PROTECTED:
                target = m_Ship;
                break;
            case State.STATE_BACK:
                target = m_Slot.gameObject;
                CurFlyVelocity = Mathf.Clamp((m_Slot.transform.position - transform.position).magnitude / 3, 0.1f, 1) * FlyVelocity;
                CurFlyVelocity = Mathf.Max(CurFlyVelocity, 1.5f);
                break;
        }

        if (m_SlotOfUVA && m_Ship && !m_SlotOfUVA.m_Ship)
            m_SlotOfUVA.m_Ship = m_Ship.GetComponent<Ship>();

        if (target)
        {
            var targetDefference = target.transform.position - transform.position;
            float distance = targetDefference.magnitude;
            Missile missle = m_SlotOfUVA.m_Weapon as Missile;
            if (missle != null)
            {
                bool license = missle.ShutRange / 3 < distance;
                m_SlotOfUVA.m_FireLicense = license;
                missle.m_Target = m_Target;
            }

            float trunVelocity = 100;
            bool isFight = false;
            UAV uav = m_Weapon as UAV;
            if (uav != null)
            {
                trunVelocity = uav.m_TrunVelocity;
                isFight = (uav.m_UAVType == UAV.UAVType.TYPE_FIGHT);
            }

            var sideDir =Vector3.Cross(targetDefference, FlyDirection);

            if(SelfDestruct)
            {
                FlyDirection = targetDefference.normalized;
            }
            else
            {
                //  围着目标旋转，然后开火
                float weaonRange = m_SlotOfUVA.m_Weapon.ShutRange * 0.7f;
                if (isFight && distance < weaonRange && m_State == State.STATE_FIGHT)
                {
                    if (RotaDir)
                        sideDir = Vector3.Cross(Vector3.Cross(targetDefference, Vector3.forward), FlyDirection);
                    else
                        sideDir = -Vector3.Cross(Vector3.Cross(targetDefference, Vector3.forward), FlyDirection);
                }
                var d = sideDir.z;
                if (d >= 0)
                {
                    FlyDirection = Quaternion.AngleAxis(trunVelocity * Time.deltaTime, new Vector3(0, 0, -1)) * FlyDirection;
                }
                else
                {
                    FlyDirection = Quaternion.AngleAxis(trunVelocity * Time.deltaTime, new Vector3(0, 0, 1)) * FlyDirection;
                }
            }
        }
        else
        {
            m_State = State.STATE_PROTECTED;
        }

        transform.rotation = Quaternion.FromToRotation(Vector3.up, FlyDirection);
        var moveOffset = FlyDirection * (CurFlyVelocity * Time.deltaTime);
        Life -= moveOffset.magnitude;
        transform.position += moveOffset;
        if (m_SlotOfUVA)
        {
            m_SlotOfUVA.m_FireLicense = m_AmmoCapacity > 0;
        }
    }

    public void FixedUpdate()
    {
        if (UtilsGame.IsOnline() && !UtilsGame.IsServer(gameObject))
        {
            return;
        }
        if (!Target && null != m_Influence)
        {
            float distance = 1000000000000;
            for (int i = 0; i < ShipManager.Instance.NumShips; ++i)
            {
                var ship = ShipManager.Instance.GetShip(i);
                var shipCom = ship.GetComponent<Ship>();
                if (ship.gameObject.activeSelf && InfluenceMG.get().isHostile(m_Influence, shipCom.m_ShipStruct.Influence))
                {
                    var defference = ship.transform.position - transform.position;
                    if (defference.magnitude < distance)
                    {
                        distance = defference.magnitude;
                        Target = ship.gameObject;
                    }
                }
            }
        }
    }
    protected override void OnDestroy()
    {
        base.OnDestroy();
    }
    
    public void Boom(float damage, Weapon.DamageType damageType)
    {
        switch (damageType)
        {
            case Weapon.DamageType.TYPE_EXPLOSION:
                damage *= 2;
                break;
            case Weapon.DamageType.TYPE_KINETIC:
                damage /= 2;
                break;
        }
        m_HP -= damage;

        if (m_HP <= 0)
        {
            OnBoom();
        }
    }
    override protected void OnTriggerEnter2D(Collider2D collision)
    {
        if (UtilsGame.IsOnline() && !UtilsGame.IsServer(gameObject))
        {
            return;
        }
        if(SelfDestruct)
        {
            base.OnTriggerEnter2D(collision);
            return;
        }
        if (m_Slot != null && collision.gameObject == m_Slot.gameObject && m_State == State.STATE_BACK)
        {
            OnRangeMax();
            OnRecycleUAV();
        }
    }

    override public void InitParameter(Vector3 position, Vector3 direction, float flyVelocity, float range, float damge, string weaponClassName, Weapon.DamageType dameageType, Ship ship, Weapon weapon)
    {
        m_AmmoCapacity = 1;
        SelfDestruct = false;
        float randomValue = UnityEngine.Random.Range(0.9f, 1.1f);
        flyVelocity *= randomValue;
        if (randomValue > 1)
            RotaDir = true;
        else
            RotaDir = false;
        base.InitParameter(position, direction, flyVelocity, range, damge, weaponClassName,dameageType, ship, weapon);
        FlyItemManager.Instance.AddFlyItem(this);
        m_State = State.STATE_FIGHT;
        if (m_SlotOfUVA != null)
            m_SlotOfUVA.m_FireReady = true;
    }
    protected override void OnBoom()
    {
        base.OnBoom();
        OnDesctroyUAV();
    }

    void OnDesctroyUAV()
    {
        UAV uav = m_Weapon as UAV;
        if (uav != null)
        {
            uav.RemoveUAV(this);
        }
        FlyItemManager.Instance.RemoveFlyItem(this);
    }

    void OnRecycleUAV()
    {
        UAV uav = m_Weapon as UAV;
        if (uav != null)
        {
            uav.Recycle(this);
        }
        FlyItemManager.Instance.RemoveFlyItem(this);
    }

    void OnFireCallback()
    {
        m_AmmoCapacity--;
    }
}